<template>
  <el-backtop :right="150" :bottom="100" />

  <!-- 居中搜索框 -->
  <div class="search-container-wrapper">
    <div class="search-container">
      <el-input
          v-model="searchTitle"
          placeholder="搜索文章标题..."
          class="search-input"
          clearable
          @clear="resetSearch"
          @keyup.enter="handleSearch"
          @input="handleSearch">
        <template #append>
          <el-button :icon="Search" @click="handleSearch"></el-button>
        </template>
      </el-input>
    </div>
  </div>

  <div v-infinite-scroll="load" infinite-scroll-delay="1000" infinite-scroll-distance="100px"
       infinite-scroll-immediate="false">
    <!-- 搜索结果计数 -->
    <div v-if="isSearchActive" class="search-results">
      找到 {{ total }} 条与 "{{ searchTitle }}" 相关的结果
      <el-button type="text" @click="resetSearch">清除搜索</el-button>
    </div>

    <!-- 文章列表容器 -->
    <div class="article-list-container">
      <!-- 瀑布流布局容器 -->
      <div class="masonry-container" ref="masonryContainer">
        <article-card
            v-for="item in homeList"
            :key="item.id"
            :article="item"
            :img-url="imgUrl"
            @click="item.categoryId === 4 ? viewShortArticle(item) : openDetail(item.id)"
        />
      </div>
    </div>

    <!-- 没有搜索结果 -->
    <div v-if="homeList.length === 0" class="no-results">
      <el-empty description="没有找到相关文章" :image-size="200">
        <el-button v-if="isSearchActive" type="primary" @click="resetSearch">
          返回全部文章
        </el-button>
      </el-empty>
    </div>
  </div>

  <!-- 短文查看对话框 -->
  <el-dialog
      v-model="shortArticleDialogVisible"
      :title="currentShortArticle.articleTitle"
      width="65%"
      destroy-on-close
      class="short-article-dialog">
    <div class="short-article-content">
      <div class="short-article-meta">
        <div class="short-article-category">
          <el-tag effect="light">{{ currentShortArticle.categoryName }}</el-tag>
        </div>
        <div class="short-article-time">
          <el-icon size="14">
            <Timer />
          </el-icon>
          <span>
            {{ currentShortArticle.createTime ? $filters.timeFilter(currentShortArticle.createTime) : '' }}
          </span>
        </div>
      </div>

      <div v-if="currentShortArticle.articleImg" class="short-article-image">
        <img :src="imgUrl + currentShortArticle.articleImg" alt="文章图片">
      </div>

      <div class="short-article-body">
        {{ currentShortArticle.articleContent || currentShortArticle.articleExcerpt }}
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, h, computed, nextTick, onMounted, onUnmounted } from "vue"
import { listHome } from "@/api/bk/home";
import { ElNotification } from 'element-plus'
import { useRouter } from 'vue-router';
import { Picture, Timer, View, Search, ArrowRight } from '@element-plus/icons-vue'

// 文章卡片组件
const ArticleCard = {
  name: 'ArticleCard',
  props: {
    article: {
      type: Object,
      required: true
    },
    imgUrl: {
      type: String,
      required: true
    }
  },
  emits: ['click'],
  setup(props, { emit }) {
    const cardRef = ref(null);

    const handleClick = () => {
      emit('click')
    }

    // 根据图片比例和类型计算卡片尺寸类
    const getCardSizeClass = () => {
      const { article } = props;

      // 短文类型的卡片 - 固定中等尺寸
      if (article.categoryId === 4) {
        return 'masonry-item-medium';
      }

      // 根据标题长度和内容长度计算尺寸
      const titleLength = article.articleTitle ? article.articleTitle.length : 0;
      const excerptLength = article.articleExcerpt ? article.articleExcerpt.length : 0;

      // 随机性因子 - 基于文章ID生成伪随机数
      const randomFactor = (article.id % 7) + 1;

      // 综合计算卡片大小
      const sizeScore = titleLength + excerptLength * 0.5 + randomFactor * 10;

      if (sizeScore > 80) return 'masonry-item-large';
      if (sizeScore > 50) return 'masonry-item-medium';
      return 'masonry-item-small';
    }

    return {
      cardRef,
      handleClick,
      getCardSizeClass,
      Picture,
      Timer,
      View,
      ArrowRight
    }
  },
  template: `
    <!-- 短文横向卡片 -->
    <div
        v-if="article.categoryId === 4"
        :class="['masonry-item', 'short-article-item', getCardSizeClass()]"
        ref="cardRef"
        @click="handleClick">
      <el-card class="short-article-card" shadow="hover">
        <div class="short-article-layout">
          <!-- 左侧图片区域 -->
          <div class="short-article-image-section">
            <div class="short-article-image-wrapper">
              <img
                  v-if="article.articleImg"
                  :src="imgUrl + article.articleImg"
                  class="short-article-image"
                  alt="封面图">
              <div v-else class="short-article-image-placeholder">
                <el-icon :size="28" color="#909399">
                  <Picture />
                </el-icon>
              </div>
              <!-- 分类标签 -->
              <el-tag class="article-category-tag" effect="light" size="small">
                {{ article.categoryName }}
              </el-tag>
            </div>
          </div>

          <!-- 右侧内容区域 -->
          <div class="short-article-content-section">
            <div class="short-article-content">
              <!-- 标题 -->
              <h3 class="article-title">{{ article.articleTitle }}</h3>

              <!-- 摘要 -->
              <p class="article-excerpt">{{ article.articleExcerpt }}</p>

              <!-- 底部信息 -->
              <div class="article-footer">
                <div class="article-meta">
                  <el-icon size="14" class="meta-icon">
                    <Timer />
                  </el-icon>
                  <span class="meta-text">
                    {{ $filters.timeFilter(article.createTime) }}
                  </span>
                </div>
                <div class="read-hint">
                  点击查看全文
                  <el-icon class="read-arrow">
                    <ArrowRight />
                  </el-icon>
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 标准竖直卡片 -->
    <div v-else :class="['masonry-item', 'standard-article-item', getCardSizeClass()]"
         ref="cardRef" @click="handleClick">
      <el-card class="standard-article-card" shadow="hover">
        <!-- 封面图片 -->
        <div class="standard-article-image-wrapper">
          <img
              v-if="article.articleImg"
              :src="imgUrl + article.articleImg"
              class="standard-article-image"
              alt="封面图">
          <div v-else class="standard-article-image-placeholder">
            <el-icon :size="36" color="#909399">
              <Picture />
            </el-icon>
          </div>
          <!-- 分类标签 -->
          <el-tag class="article-category-tag" effect="light" size="small">
            {{ article.categoryName }}
          </el-tag>
        </div>

        <!-- 内容区域 -->
        <div class="standard-article-content">
          <h3 class="article-title">{{ article.articleTitle }}</h3>
          <p class="article-excerpt">{{ article.articleExcerpt }}</p>

          <!-- 底部信息 -->
          <div class="article-footer">
            <div class="article-meta">
              <el-icon size="14" class="meta-icon">
                <Timer />
              </el-icon>
              <span class="meta-text">{{ $filters.timeFilter(article.createTime) }}</span>
            </div>
            <div class="article-meta">
              <el-icon size="14" class="meta-icon">
                <View />
              </el-icon>
              <span class="meta-text">{{ article.viewCount }}</span>
            </div>
          </div>
        </div>
      </el-card>
    </div>
  `
}

const router = useRouter();
const imgUrl = import.meta.env.VITE_API_BASE_URL
const homeList = ref([])
const total = ref(0);
const searchTitle = ref('');
const isSearchActive = computed(() => searchTitle.value.trim() !== '');
const masonryContainer = ref(null);

// 短文查看相关变量
const shortArticleDialogVisible = ref(false);
const currentShortArticle = ref({});

const queryParams = ref({
  pageNum: 1,
  pageSize: 8,
  status: 1,
  articleTitle: ''
})

/** 查询文章列表 */
function getList() {
  listHome(queryParams.value).then(response => {
    homeList.value = response.rows;
    total.value = response.total;

    // 延迟执行瀑布流布局
    nextTick(() => {
      setTimeout(initMasonry, 100);
    });
  });
}

// 瀑布流布局初始化
function initMasonry() {
  if (!masonryContainer.value) return;

  const container = masonryContainer.value;
  const items = container.querySelectorAll('.masonry-item');

  // 清除之前的定位
  items.forEach(item => {
    item.style.position = '';
    item.style.top = '';
    item.style.left = '';
  });

  // 获取容器宽度和间距
  const containerWidth = container.offsetWidth;
  const gap = 20;

  // 计算列数和列宽
  let columnCount;
  let columnWidth;

  if (containerWidth >= 1200) {
    columnCount = 4;
  } else if (containerWidth >= 900) {
    columnCount = 3;
  } else if (containerWidth >= 600) {
    columnCount = 2;
  } else {
    columnCount = 1;
  }

  columnWidth = (containerWidth - gap * (columnCount - 1)) / columnCount;

  // 初始化列高度数组
  const columnHeights = new Array(columnCount).fill(0);

  items.forEach((item, index) => {
    // 设置项目宽度
    item.style.width = `${columnWidth}px`;

    // 找到最短的列
    const shortestColumnIndex = columnHeights.indexOf(Math.min(...columnHeights));

    // 设置项目位置
    item.style.position = 'absolute';
    item.style.left = `${shortestColumnIndex * (columnWidth + gap)}px`;
    item.style.top = `${columnHeights[shortestColumnIndex]}px`;

    // 更新列高度
    const itemHeight = item.offsetHeight;
    columnHeights[shortestColumnIndex] += itemHeight + gap;
  });

  // 设置容器高度
  const maxHeight = Math.max(...columnHeights);
  container.style.height = `${maxHeight}px`;
}

// 处理搜索操作
function handleSearch() {
  queryParams.value.pageNum = 1;
  queryParams.value.articleTitle = searchTitle.value.trim();
  homeList.value = [];
  getList();
}

// 重置搜索
function resetSearch() {
  searchTitle.value = '';
  queryParams.value.articleTitle = '';
  queryParams.value.pageNum = 1;
  homeList.value = [];
  getList();
}

// 加载更多
function load() {
  // 已加载全部数据时，直接返回
  if (homeList.value.length >= total.value) {
    ElNotification({
      title: '提示',
      duration: 3000,
      message: h('i', { style: 'color: teal' }, '已经刷到底了哦~(*^_^*)'),
    })
    return
  }
  queryParams.value.pageNum += 1
  listHome(queryParams.value).then(response => {
    homeList.value = homeList.value.concat(response.rows);
    total.value = response.total;

    // 延迟执行瀑布流布局
    nextTick(() => {
      setTimeout(initMasonry, 100);
    });
  });
}

// 普通文章详情页
const openDetail = (id) => {
  const url = router.resolve({
    name: 'Detail',
    params: { id }
  }).href;
  window.open(url, '_blank');
};

// 直接查看短文
const viewShortArticle = (article) => {
  currentShortArticle.value = article;
  shortArticleDialogVisible.value = true;
};

// 窗口大小改变时重新布局
const handleResize = () => {
  setTimeout(initMasonry, 100);
};

onMounted(() => {
  getList();
  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});
</script>

<style lang="scss">
.el-card__body {
  padding: 0;
}

.el-image {
  display: block;
}

/* 搜索框样式 */
.search-container-wrapper {
  display: flex;
  justify-content: center;
  width: 100%;
  margin: 20px 0 30px;
  padding: 0 15px;
  box-sizing: border-box;
}

.search-container {
  background-color: rgba(255, 255, 255, 0.6);
  width: 100%;
  max-width: 500px;
  padding: 8px;
  display: flex;
  justify-content: center;
  border-radius: 20px;
  backdrop-filter: blur(8px);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;

  &:hover {
    background-color: rgba(255, 255, 255, 0.75);
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  }
}

.search-input {
  width: 100%;
  background-color: transparent;

  :deep(.el-input__wrapper) {
    border-radius: 20px !important;
    background-color: rgba(255, 255, 255, 0.7) !important;
    backdrop-filter: blur(5px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
    border: none !important;
    padding: 0 10px;
    transition: all 0.3s ease;

    &:hover,
    &:focus-within {
      background-color: rgba(255, 255, 255, 0.9) !important;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;
    }
  }

  :deep(.el-input-group__append) {
    border-top-right-radius: 20px !important;
    border-bottom-right-radius: 20px !important;
    background-color: rgba(144, 238, 144, 0.5) !important;
    border: none !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1) !important;

    .el-button {
      border: none;
      background: transparent;
      color: #2c3e50;

      &:hover {
        color: #000;
      }
    }
  }
}

.search-results {
  max-width: 500px;
  margin: 0 auto 20px;
  padding: 8px 16px;
  font-size: 14px;
  color: #606266;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.6);
  border-radius: 16px;
  backdrop-filter: blur(5px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.no-results {
  margin: 40px auto;
  text-align: center;

  .el-empty {
    background-color: rgba(255, 255, 255, 0.7);
    border-radius: 20px;
    padding: 20px;
    max-width: 500px;
    margin: 0 auto;
    backdrop-filter: blur(5px);
  }

  .el-button {
    border-radius: 20px;
    background-color: rgba(144, 238, 144, 0.6);
    border: none;
    color: #2c3e50;
    font-weight: 500;

    &:hover {
      background-color: rgba(144, 238, 144, 0.8);
      color: #000;
    }
  }
}

/* 瀑布流布局容器 */
.article-list-container {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 15px;
}

.masonry-container {
  position: relative;
  width: 100%;
  margin: 0 auto;
}

/* 瀑布流项目基础样式 */
.masonry-item {
  cursor: pointer;
  transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
  margin-bottom: 20px;

  &:hover {
    transform: translateY(-8px) scale(1.02);
    z-index: 10;
  }
}

/* 不同尺寸的卡片样式 */
.masonry-item-small {
  .standard-article-image-wrapper {
    height: 140px;
  }

  .article-title {
    font-size: 14px;
    -webkit-line-clamp: 2;
  }

  .article-excerpt {
    font-size: 12px;
    -webkit-line-clamp: 2;
  }
}

.masonry-item-medium {
  .standard-article-image-wrapper {
    height: 180px;
  }

  .article-title {
    font-size: 16px;
    -webkit-line-clamp: 2;
  }

  .article-excerpt {
    font-size: 14px;
    -webkit-line-clamp: 3;
  }
}

.masonry-item-large {
  .standard-article-image-wrapper {
    height: 220px;
  }

  .article-title {
    font-size: 18px;
    -webkit-line-clamp: 3;
  }

  .article-excerpt {
    font-size: 14px;
    -webkit-line-clamp: 4;
  }
}

/* 短文特殊样式 - 减小尺寸 */
.short-article-item {
  .short-article-layout {
    min-height: 140px;
  }

  .short-article-image-section {
    flex: 0 0 35%;
    min-height: 140px;
  }

  .short-article-image-placeholder {
    min-height: 140px;
  }

  .short-article-content {
    padding: 16px;
  }

  .article-title {
    font-size: 15px;
    margin-bottom: 8px;
  }

  .article-excerpt {
    font-size: 13px;
    -webkit-line-clamp: 2;
  }
}

/* 卡片通用样式 */
.short-article-card,
.standard-article-card {
  border-radius: 16px !important;
  overflow: hidden;
  background-color: rgba(255, 255, 255, 0.75) !important;
  backdrop-filter: blur(8px);
  transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important;
  height: fit-content;
  border: 1px solid rgba(255, 255, 255, 0.2);

  &:hover {
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.15) !important;
    background-color: rgba(255, 255, 255, 0.9) !important;
    border-color: rgba(144, 238, 144, 0.3);
  }

  :deep(.el-card__body) {
    padding: 0 !important;
  }
}

/* 短文卡片布局 */
.short-article-layout {
  display: flex;
  height: auto;
}

.short-article-image-section {
  position: relative;
}

.short-article-image-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  border-radius: 12px 0 0 12px;
}

.short-article-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.short-article-card:hover .short-article-image {
  transform: scale(1.1);
}

.short-article-image-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}

.short-article-content-section {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.short-article-content {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* 标准文章卡片样式 */
.standard-article-image-wrapper {
  position: relative;
  overflow: hidden;
  width: 100%;
}

.standard-article-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.standard-article-card:hover .standard-article-image {
  transform: scale(1.08);
}

.standard-article-image-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}

.standard-article-content {
  padding: 16px;
}

/* 通用内容样式 */
.article-title {
  margin: 0 0 10px 0;
  font-weight: 600;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  line-height: 1.4;
  transition: color 0.3s ease;
}

.article-excerpt {
  margin: 0 0 16px 0;
  line-height: 1.6;
  color: #606266;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}

.article-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 12px;
  border-top: 1px dashed rgba(234, 234, 234, 0.8);
  margin-top: auto;
}

.article-meta {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #909399;

  .meta-icon {
    margin-right: 4px;
  }

  .meta-text {
    font-size: 12px;
  }
}

/* 分类标签 */
.article-category-tag {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 4px 10px;
  background: rgba(144, 238, 144, 0.9);
  border: none;
  color: #2c3e50;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  z-index: 2;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(4px);
}

/* 阅读提示 */
.read-hint {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #67c23a;
  font-weight: 500;

  .read-arrow {
    margin-left: 4px;
    transition: transform 0.3s ease;
  }
}

.short-article-item:hover .read-arrow {
  transform: translateX(4px);
}

/* 短文对话框样式 */
.short-article-dialog {
  :deep(.el-dialog__header) {
    padding: 24px 24px 0;
    text-align: center;
  }

  :deep(.el-dialog__title) {
    font-size: 24px;
    font-weight: 600;
    color: #303133;
  }

  :deep(.el-dialog__body) {
    padding: 24px;
  }
}

.short-article-content {
  max-width: 800px;
  margin: 0 auto;
}

.short-article-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #eaeaea;
}

.short-article-time {
  display: flex;
  align-items: center;
  color: #909399;
  font-size: 14px;

  .el-icon {
    margin-right: 6px;
  }
}

.short-article-image {
  margin: 0 auto 20px;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  max-width: 500px;

  img {
    width: 100%;
    height: auto;
    max-height: 300px;
    display: block;
    object-fit: contain;
  }
}

.short-article-body {
  font-size: 16px;
  line-height: 1.8;
  color: #303133;
  white-space: pre-line;
}

/* 响应式设计 */
@media (max-width: 600px) {
  .article-list-container {
    padding: 0 10px;
  }

  .short-article-layout {
    flex-direction: column;
  }

  .short-article-image-section {
    flex: none;
    height: 160px;
  }

  .short-article-image-wrapper {
    border-radius: 12px 12px 0 0;
  }

  .masonry-item-small .standard-article-image-wrapper {
    height: 120px;
  }

  .masonry-item-medium .standard-article-image-wrapper {
    height: 140px;
  }

  .masonry-item-large .standard-article-image-wrapper {
    height: 160px;
  }
}

@media (max-width: 480px) {
  .search-container-wrapper {
    padding: 0 10px;
  }

  .search-container {
    padding: 6px;
  }

  .article-title {
    font-size: 14px !important;
  }

  .article-excerpt {
    font-size: 12px !important;
  }
}
</style>